using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Emlyn.Applications.Scratch.Graphics.Tools;
using Microsoft.DirectX.Direct3D;

namespace Emlyn.Applications.Scratch.Graphics.Dragon1
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        DirectXWrapper _wrapper = null;
        ScrollingBackground _scrollingBackground = null;

        Bitmap _tilesBitmap = null;
        MapData _mapData = null;
        DragonClass _dragon = null;
        Textures _dragontextures = null;
        EAnimatedDirectionSprite _dragonshadow = null;
        Textures _dragonshadowtextures = null;

        int ScrollX = 0;
        int ScrollY = 0;
        int FlightHeight = 20;
        bool EndZone = false;

        const int TileWidth = 64;
        const int TileHeight = 48;
        const int ScrollStep = 8;

        bool _closing = false;

        private void frmMain_Load(object sender, EventArgs e)
        {
            //            _tilesBitmap = new Bitmap(@"x:\emlyn\images\pipemap.bmp");
            MessageBox.Show(AppDomain.CurrentDomain.BaseDirectory);

            _tilesBitmap = new Bitmap(AppDomain.CurrentDomain.BaseDirectory + @"..\..\images\map\grasslevel.bmp");

            _mapData = new MapData();

            _mapData.LoadFromFile(AppDomain.CurrentDomain.BaseDirectory + @"..\..\images\map\grasslevel.csv", 20);
            //_mapData.QuadrupleSize();
            //_mapData.QuadrupleSize();
            //_mapData.QuadrupleSize();
            //_mapData.QuadrupleSize();
            //_mapData.QuadrupleSize();

            //ScrollY = GameWorldHeight() - ClientSize.Height;
            //ScrollX = ((GameWorldWidth() - ClientSize.Width) / 2);

            _dragon = new DragonClass(
                null,
                new Size(),
                null,
                9,
                1
            );

            _dragonshadow = new EAnimatedDirectionSprite(
                null,
                new Size(),
                null,
                9,
                1
            );

            InitAll();

            _dragon.SpeedStep = 8;
            _dragon.Pos = new Point(
                (GameWorldWidth() - ClientSize.Width) / 2,
                GameWorldHeight() - ClientSize.Height
            );
            _dragon.Facing = EDirection.North;

            _wrapper._device.DeviceLost += new EventHandler(DeviceLostHandler);
        }

        private void DisposeAll(bool aFull)
        {
            if (aFull)
            {
                if (_dragon != null)
                {
                    _dragon.Dispose();
                    _dragon = null;
                }
                if (_dragonshadow != null)
                {
                    _dragonshadow.Dispose();
                    _dragonshadow = null;
                }
            }

            if (_scrollingBackground != null)
            {
                _scrollingBackground.Dispose();
                _scrollingBackground = null;
            }
            if (_wrapper != null)
            {
                _wrapper.Dispose();
                _wrapper = null;
            }
        }

        private void InitAll()
        {
            timer1.Enabled = false;

            try
            {
                DisposeAll(false);

                _wrapper = new DirectXWrapper(this.ClientSize.Width, this.ClientSize.Height, this);

                _scrollingBackground = new ScrollingBackground(_wrapper, _tilesBitmap, TileWidth, TileHeight, _mapData);

                _dragontextures = new Textures(_wrapper);

                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt n????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt ne????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt e????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt se????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt s????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt sw????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt w????.bmp");
                _dragontextures.AddTextures(@"..\..\images\dragon", @"fliegt nw????.bmp");

                _dragonshadowtextures = new Textures(_wrapper);

                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten n????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten ne????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten e????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten se????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten s????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten sw????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten w????.bmp");
                _dragonshadowtextures.AddTextures(@"..\..\images\dragon", @"flugschatten nw????.bmp");

                _dragon.ResetDirectXWrapper(
                    _wrapper,
                    new Size(
                        _dragontextures[0].GetLevelDescription(0).Width,
                        _dragontextures[0].GetLevelDescription(0).Height
                    )
                );
                _dragon.ResetTextures(_dragontextures);

                _dragonshadow.ResetDirectXWrapper(
                    _wrapper,
                    new Size(
                        _dragonshadowtextures[0].GetLevelDescription(0).Width,
                        _dragonshadowtextures[0].GetLevelDescription(0).Height
                    )
                );
                _dragonshadow.ResetTextures(_dragonshadowtextures);
            }
            finally
            {
                timer1.Enabled = true;
            }
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            timer1.Enabled = false;
            DisposeAll(true);
        }

        private void DeviceLostHandler(object sender, EventArgs e)
        {
            if (!_closing)
            {
                InitAll();
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            UpdateScrollPosition();

            _scrollingBackground.BuildTileBuffer(
                ScrollX, 
                ScrollY, 
                _wrapper._backbuffer.Description.Width, 
                _wrapper._backbuffer.Description.Height
                );

            _scrollingBackground.WriteBackgroundOntoBackBuffer(
                ScrollX, 
                ScrollY
                );

            _wrapper._device.BeginScene();

            //_dragonshadow.Pos = new Point(
            //    _wrapper._backbuffer.Description.Width / 2 - (_dragon.SpriteSize.Width/2),
            //    _wrapper._backbuffer.Description.Height / 2 - (_dragon.SpriteSize.Height/2)
            //    );

            //_dragon.Pos = new Point(
            //    _dragonshadow.Pos.X - FlightHeight / 3,
            //    _dragonshadow.Pos.Y - FlightHeight
            //    );

            //_dragonshadow.Facing = _dragon.Facing;

            //_dragonshadow.Draw();

            _dragon.Draw(ScrollX, ScrollY);

            _wrapper._device.EndScene();

            _wrapper.Present();
        }

        private int GameWorldWidth()
        {
            return _mapData.Width * TileWidth;
        }

        private int GameWorldHeight()
        {
            return _mapData.Height * TileHeight;
        }

        private int ViewPortWidth()
        {
            return _wrapper._backbuffer.Description.Width;
        }

        private int ViewPortHeight()
        {
            return _wrapper._backbuffer.Description.Height;
        }

        private void UpdateScrollPosition()
        {
//            EndZone = ScrollY < TileHeight * 20;
            EndZone = _dragon.Pos.Y < TileHeight * 20;

            //if (!EndZone)
            //    _dragon.SpeedY = -1 * ScrollStep;

            _dragon.IncrementPos();

            if (
                _dragon.Pos.X < 0 ||
                _dragon.Pos.X > (GameWorldWidth() - _dragon.SpriteSize.Width) ||
                _dragon.Pos.Y < 0 ||
                _dragon.Pos.Y > (GameWorldHeight() - _dragon.SpriteSize.Height)
                )
            {
                _dragon.DecrementPos();
            }

            ScrollX = Math.Min(Math.Max(_dragon.Pos.X - (ViewPortWidth() /2) + (_dragon.SpriteSize.Width/2),0), (GameWorldWidth() - ViewPortWidth()));
            ScrollY = Math.Min(Math.Max(_dragon.Pos.Y - (ViewPortHeight() / 2) + (_dragon.SpriteSize.Height / 2), 0), (GameWorldHeight() - ViewPortHeight()));

            //ScrollX += _dragon.SpeedX;
            //if (ScrollX < 0)
            //{
            //    ScrollX = 0;
            //    _dragon.SpeedX = 0;
            //}
            //else if (ScrollX > GameWorldWidth() - _wrapper._backbuffer.Description.Width - 1)
            //{
            //    ScrollX = GameWorldWidth() - _wrapper._backbuffer.Description.Width - 1;
            //    _dragon.SpeedX = 0;
            //}

            //ScrollY += _dragon.SpeedY;
            //if (ScrollY < 0)
            //{
            //    ScrollY = 0;
            //    _dragon.SpeedY = 0;
            //}
            //else if (ScrollY > GameWorldHeight() - _wrapper._backbuffer.Description.Height - 1)
            //{
            //    ScrollY = GameWorldHeight() - _wrapper._backbuffer.Description.Height - 1;
            //    _dragon.SpeedY = 0;
            //}

            //if (_dragon.SpeedX < 0)
            //{
            //    if (_dragon.SpeedY < 0)
            //    {
            //        _dragon.Facing = EDirection.NorthWest;
            //    }
            //    else if (_dragon.SpeedY > 0)
            //    {
            //        _dragon.Facing = EDirection.SouthWest;
            //    }
            //    else
            //    {
            //        _dragon.Facing = EDirection.West;
            //    }
            //}
            //else if (_dragon.SpeedX > 0)
            //{
            //    if (_dragon.SpeedY < 0)
            //    {
            //        _dragon.Facing = EDirection.NorthEast;
            //    }
            //    else if (_dragon.SpeedY > 0)
            //    {
            //        _dragon.Facing = EDirection.SouthEast;
            //    }
            //    else
            //    {
            //        _dragon.Facing = EDirection.East;
            //    }
            //}
            //else
            //{
            //    if (_dragon.SpeedY < 0)
            //    {
            //        _dragon.Facing = EDirection.North;
            //    }
            //    else if (_dragon.SpeedY > 0)
            //    {
            //        _dragon.Facing = EDirection.South;
            //    }
            //    else
            //    {
            //        // nothing
            //    }
            //}
        }

        private void frmMain_MouseMove(object sender, MouseEventArgs e)
        {
            //if (e.X < _wrapper._backbuffer.Description.Width / 3)
            //    _dragon.SpeedX = -1 * ScrollStep;
            //else if (e.X > 2 * _wrapper._backbuffer.Description.Width / 3)
            //    _dragon.SpeedX = ScrollStep;
            //else
            //    _dragon.SpeedX = 0;

            //if (e.Y < _wrapper._backbuffer.Description.Height / 3)
            //    _dragon.SpeedY = -1 * ScrollStep;
            //else if (e.Y > 2 * _wrapper._backbuffer.Description.Height / 3)
            //    _dragon.SpeedY = ScrollStep;
            //else
            //    _dragon.SpeedY = 0;
        }

        private void frmMain_HelpButtonClicked(object sender, CancelEventArgs e)
        {

        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            _closing = true;
        }

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
                Close();
            else if (e.KeyCode == Keys.Down)
                FlightHeight = Math.Max(0, FlightHeight - 2);
            else if (e.KeyCode == Keys.Up)
                FlightHeight = Math.Min(200, FlightHeight + 2);
            else
            {
                if (EndZone)
                {
                    if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
                    {
                        EDirection lnewFacing = _dragon.Facing;

                        if (e.KeyCode == Keys.Left)
                        {
                            int ldirnum = (int)lnewFacing;
                            ldirnum = ldirnum - 1;
                            if (ldirnum < 0) ldirnum = 7;
                            lnewFacing = (EDirection)ldirnum;
                        }
                        else if (e.KeyCode == Keys.Right)
                        {
                            int ldirnum = (int)lnewFacing;
                            ldirnum = ldirnum + 1;
                            if (ldirnum > 7) ldirnum = 0;
                            lnewFacing = (EDirection)ldirnum;
                        }

                        _dragon.Facing = lnewFacing;
                        //_dragon.SpeedX = EDirectionTools.EDirectionToOffsetX(lnewFacing) * ScrollStep;
                        //_dragon.SpeedY = EDirectionTools.EDirectionToOffsetY(lnewFacing) * ScrollStep;
                    }
                }
                else
                {
                    if (e.KeyCode == Keys.Left)
                    {
                        // _dragon.SpeedX = -1 * ScrollStep;
                        _dragon.Facing = EDirection.NorthWest;
                    }
                    else if (e.KeyCode == Keys.Right)
                    {
                        // _dragon.SpeedX = ScrollStep;
                        _dragon.Facing = EDirection.NorthEast;
                    }
                }
            }
        }

        private void frmMain_KeyUp(object sender, KeyEventArgs e)
        {
            if (!EndZone && (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right))
            {
                // _dragon.SpeedX = 0;
                _dragon.Facing = EDirection.North;
            }
        }
    }
}